/*
 * ECPKN master project
 * Simulation framework for
 * "A Frequency-utilization based Power-Aware Schedule Policy for Real-Time Multi-cores System"
 * Author: Lin Zhou, zhoulinelise@gmail.com
 *         Lei Yu, yulei@buaa.edu.cn
 *         Yangdi Yang, yueyongdong@gmail.com
 * */
package org.ecpkn.PAGridSim.core.Simulator;

import gridsim.AllocPolicy;
import gridsim.GridResource;
import gridsim.GridSim;
import gridsim.GridletList;

import java.util.Calendar;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.ecpkn.PAGridSim.core.PAEntityFactory;
import org.ecpkn.PAGridSim.core.configuration.Configuration;
import org.ecpkn.PAGridSim.core.configuration.Configuration.Const;
import org.ecpkn.PAGridSim.core.report.AnalyseTools;

public class Main {

	private static final Logger logger = LogManager.getLogger(Main.class);

	public static void main(String[] args) {

		logger.debug("Starting PAGridSimTest");
		try {

			// TODO:create jar,think about how to make it really independant
			// First step: Initialize the GridSim package.

			// Gets the current time as the initial simulation time.
			// Both start and end time must be greater than the initial
			// simulation time.
			Calendar calendar = Calendar.getInstance();
			logger.debug("Init simulation time = " + calendar.getTime());

			// True means trace GridSim events
			boolean trace_flag = true;

			// All the jobs come from one user
			int num_user = 1;

			// List of files or processing names to be excluded from any
			// statistical measures
			// TODO:it's unused for now
			String[] exclude_from_file = { "" };
			String[] exclude_from_processing = { "" };
			String report_name = "PAGridSimTest";

			GridSim.init(num_user, calendar, trace_flag, exclude_from_file,
					exclude_from_processing, report_name);

			// ------------------------------------------------
			// Second step: Creates one GridResource object
			// given resource name, number of Machine, time zone
			// and maximum MIPS Rating.

			String resourceName = "Resource";
			String policyId = "PAPolicy";
			String policyName = Configuration.getInstance().getParameterString(
					Const.SIMULATION_POLICY);
			AllocPolicy policy = PAEntityFactory.createCustomizedPolicy(
					policyName, resourceName, policyId);
			String optimizationName = Configuration.getInstance()
					.getParameterString(Const.SIMULATION_OPTIMIZATION);

			// only create one resource
			// the machine rating is not used, it should be changed by
			// optimization policy
			GridResource resource = ResourceCreater.createGridResource(
					resourceName,
					Configuration.getInstance().getParameterInt(
							Const.TOTAL_NODE_NUMBER), 10.0, policy);

			// ------------------------------------------------
			// Third step: Creates grid users

			double bandwidth = 1000; // bandwidth of this workload

			// creates a workload(Grisim) entity
			// it's not used directly,but it does make sense
			Workload workload = new Workload("WorkloadTest", optimizationName,
					bandwidth);

			// ------------------------------------------------
			// Fourth step: Starts the simulation
			GridSim.startGridSimulation();

			// ------------------------------------------------
			// Final step: Prints the Gridlets when this simulation is over
			GridletList newList = workload.getReceiveList();
			AnalyseTools.checkMachinesUtilizationHistory(resource);
			AnalyseTools.printGridletListResume(newList, workload.get_name());
			double missingRate = AnalyseTools.printGridletListDetailHistory(
					newList, false);
			AnalyseTools.checkEnergyAndMissingRate(missingRate, resource);
			AnalyseTools.loadPowerLineChart(workload.getOptimizedUF_(),
					resource);
			AnalyseTools.loadExecutionTraceGantt(resource
					.getResourceCharacteristics());
			AnalyseTools.printExecutionTrace(resource
					.getResourceCharacteristics());
			logger.debug("Finish PAGridSimTest ");
			logger.debug("Finish simulation time = " + Calendar.getInstance().getTime());
		} catch (Exception e) {
			logger.error("Error ...... EXCEPTION");
			e.printStackTrace();
		}
		System.exit(0);
	}
}
